#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Betaflight黑盒数据字段分析工具
分析飞行记录中的所有可用数据字段，并提供可视化建议
"""

import os
import numpy as np
import matplotlib.pyplot as plt
from orangebox import Parser
import matplotlib.font_manager as fm

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

class DataFieldAnalyzer:
    def __init__(self, log_files):
        self.log_files = log_files
        self.field_categories = {
            '陀螺仪数据': [],
            '加速度计数据': [],
            '电机数据': [],
            '遥控器数据': [],
            '电池数据': [],
            'PID数据': [],
            '设定点数据': [],
            '时间数据': [],
            '调试数据': [],
            '其他传感器数据': [],
            '未分类数据': []
        }
        self.all_fields = set()
        
    def categorize_fields(self, field_names):
        """将字段按类别分类"""
        for field in field_names:
            field_lower = field.lower()
            
            # 陀螺仪数据
            if any(keyword in field_lower for keyword in ['gyro', 'gyr', 'angular']):
                self.field_categories['陀螺仪数据'].append(field)
            # 加速度计数据
            elif any(keyword in field_lower for keyword in ['acc', 'accel']):
                self.field_categories['加速度计数据'].append(field)
            # 电机数据
            elif any(keyword in field_lower for keyword in ['motor', 'esc', 'rpm', 'throttle']):
                self.field_categories['电机数据'].append(field)
            # 遥控器数据
            elif any(keyword in field_lower for keyword in ['rc', 'command', 'stick']):
                self.field_categories['遥控器数据'].append(field)
            # 电池数据
            elif any(keyword in field_lower for keyword in ['vbat', 'current', 'voltage', 'amperage', 'mah']):
                self.field_categories['电池数据'].append(field)
            # PID数据
            elif any(keyword in field_lower for keyword in ['axisp', 'axisi', 'axisd', 'axisf', 'pid']):
                self.field_categories['PID数据'].append(field)
            # 设定点数据
            elif any(keyword in field_lower for keyword in ['setpoint', 'target']):
                self.field_categories['设定点数据'].append(field)
            # 时间数据
            elif any(keyword in field_lower for keyword in ['time', 'loop', 'iteration']):
                self.field_categories['时间数据'].append(field)
            # 调试数据
            elif any(keyword in field_lower for keyword in ['debug']):
                self.field_categories['调试数据'].append(field)
            # 其他传感器数据
            elif any(keyword in field_lower for keyword in ['mag', 'baro', 'gps', 'rssi', 'link']):
                self.field_categories['其他传感器数据'].append(field)
            else:
                self.field_categories['未分类数据'].append(field)
    
    def analyze_all_files(self):
        """分析所有文件的字段"""
        print("分析飞行记录数据字段...")
        
        for log_file in self.log_files:
            if not os.path.exists(log_file):
                print(f"文件不存在: {log_file}")
                continue
                
            print(f"\n分析文件: {os.path.basename(log_file)}")
            
            try:
                parser = Parser.load(log_file)
                field_names = parser.field_names
                
                print(f"发现 {len(field_names)} 个数据字段")
                self.all_fields.update(field_names)
                
                # 分类字段
                self.categorize_fields(field_names)
                
            except Exception as e:
                print(f"分析文件 {log_file} 时出错: {e}")
    
    def generate_analysis_report(self):
        """生成分析报告"""
        report = []
        report.append("# Betaflight黑盒数据字段分析报告")
        report.append("")
        report.append(f"## 概述")
        report.append(f"总共发现 **{len(self.all_fields)}** 个不同的数据字段")
        report.append("")
        
        # 按类别展示字段
        for category, fields in self.field_categories.items():
            if fields:
                unique_fields = list(set(fields))
                report.append(f"### {category} ({len(unique_fields)}个字段)")
                for field in sorted(unique_fields):
                    report.append(f"- `{field}`")
                report.append("")
        
        # 可视化建议
        report.append("## 数据可视化建议")
        report.append("")
        
        # 陀螺仪数据可视化
        if self.field_categories['陀螺仪数据']:
            report.append("### 🔄 陀螺仪数据分析")
            report.append("**可绘制图表**:")
            report.append("- 三轴角速度时间序列图")
            report.append("- 陀螺仪数据频谱分析（检测振动）")
            report.append("- 角速度分布直方图")
            report.append("- 陀螺仪噪声分析")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 检测机架振动问题")
            report.append("- 分析飞行平滑度")
            report.append("- 优化滤波器参数")
            report.append("")
        
        # 加速度计数据可视化
        if self.field_categories['加速度计数据']:
            report.append("### 📈 加速度计数据分析")
            report.append("**可绘制图表**:")
            report.append("- 三轴加速度时间序列图")
            report.append("- 加速度矢量幅值分析")
            report.append("- 振动频谱分析")
            report.append("- G力分布图")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 分析飞行机动性能")
            report.append("- 检测硬件振动")
            report.append("- 评估飞行激烈程度")
            report.append("")
        
        # 电机数据可视化
        if self.field_categories['电机数据']:
            report.append("### ⚡ 电机数据分析")
            report.append("**可绘制图表**:")
            report.append("- 四个电机输出对比图")
            report.append("- 电机输出分布直方图")
            report.append("- 电机负载平衡分析")
            report.append("- 油门响应曲线")
            report.append("- ESC温度和RPM关系图")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 检测电机不平衡")
            report.append("- 优化电机配置")
            report.append("- 分析电机效率")
            report.append("- 预测电机寿命")
            report.append("")
        
        # 遥控器数据可视化
        if self.field_categories['遥控器数据']:
            report.append("### 🎮 遥控器数据分析")
            report.append("**可绘制图表**:")
            report.append("- 摇杆输入时间序列图")
            report.append("- 摇杆输入分布热力图")
            report.append("- 控制输入频率分析")
            report.append("- 飞行模式切换时间线")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 分析飞行员操作习惯")
            report.append("- 优化遥控器设置")
            report.append("- 评估飞行技术水平")
            report.append("")
        
        # 电池数据可视化
        if self.field_categories['电池数据']:
            report.append("### 🔋 电池数据分析")
            report.append("**可绘制图表**:")
            report.append("- 电池电压时间曲线")
            report.append("- 电流消耗分析")
            report.append("- 功率消耗曲线")
            report.append("- 电池容量使用效率")
            report.append("- 电压降与负载关系")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 评估电池健康状态")
            report.append("- 优化飞行时间")
            report.append("- 预测电池寿命")
            report.append("- 调整低电压报警")
            report.append("")
        
        # 其他传感器数据
        if self.field_categories['其他传感器数据']:
            report.append("### 📡 其他传感器数据分析")
            report.append("**可绘制图表**:")
            report.append("- RSSI信号强度变化")
            report.append("- GPS轨迹和高度图")
            report.append("- 气压高度变化")
            report.append("- 磁力计方向数据")
            report.append("- 链路质量分析")
            report.append("")
            report.append("**分析价值**:")
            report.append("- 评估信号覆盖范围")
            report.append("- 分析飞行路径")
            report.append("- 检测信号干扰")
            report.append("")
        
        # 高级分析建议
        report.append("## 🚀 高级分析建议")
        report.append("")
        
        report.append("### 多维度关联分析")
        report.append("- **电机-电池关联**: 分析电机负载与电池消耗的关系")
        report.append("- **控制-响应关联**: 分析遥控器输入与飞行器响应的延迟")
        report.append("- **环境-性能关联**: 分析环境因素对飞行性能的影响")
        report.append("")
        
        report.append("### 性能评估指标")
        report.append("- **飞行平滑度**: 基于陀螺仪数据计算")
        report.append("- **能效比**: 功率消耗与飞行性能的比值")
        report.append("- **控制精度**: 设定点与实际值的偏差分析")
        report.append("- **系统稳定性**: 各传感器数据的一致性分析")
        report.append("")
        
        report.append("### 故障诊断分析")
        report.append("- **振动检测**: 通过频谱分析检测异常振动")
        report.append("- **电机故障**: 通过电机输出不平衡检测")
        report.append("- **传感器故障**: 通过数据异常值检测")
        report.append("- **信号问题**: 通过RSSI和链路质量分析")
        report.append("")
        
        # 实用工具建议
        report.append("## 🛠️ 推荐分析工具")
        report.append("")
        report.append("### 可以创建的专用分析脚本")
        report.append("1. **电机平衡分析器** - 检测四个电机输出是否平衡")
        report.append("2. **振动频谱分析器** - 分析机架和螺旋桨振动")
        report.append("3. **电池健康监测器** - 评估电池性能和寿命")
        report.append("4. **飞行技巧评估器** - 分析飞行员操作水平")
        report.append("5. **信号质量监测器** - 分析遥控信号稳定性")
        report.append("6. **综合性能仪表板** - 多维度性能展示")
        report.append("")
        
        return report
    
    def create_sample_visualizations(self):
        """创建示例可视化图表"""
        print("\n创建示例可视化图表...")
        
        # 选择第一个可用的日志文件进行示例
        sample_file = None
        for log_file in self.log_files:
            if os.path.exists(log_file):
                sample_file = log_file
                break
        
        if not sample_file:
            print("没有找到可用的日志文件")
            return
        
        try:
            parser = Parser.load(sample_file)
            data = {}
            field_names = parser.field_names
            
            # 提取数据
            for field in field_names:
                data[field] = []
            
            for frame in parser.frames():
                if frame.data is not None:
                    for i, field in enumerate(field_names):
                        if i < len(frame.data) and frame.data[i] is not None:
                            data[field].append(frame.data[i])
                        else:
                            data[field].append(0)
            
            # 转换为numpy数组
            for field in data:
                data[field] = np.array(data[field])
            
            # 创建输出目录
            output_dir = "d:/Git/FlightRecord/SFPV_85/field_analysis_results"
            os.makedirs(output_dir, exist_ok=True)
            
            # 示例1: 电机输出对比图
            motor_fields = [f for f in field_names if 'motor' in f.lower()]
            if len(motor_fields) >= 4:
                plt.figure(figsize=(12, 8))
                for i, field in enumerate(motor_fields[:4]):
                    plt.subplot(2, 2, i+1)
                    plt.plot(data[field])
                    plt.title(f'{field}')
                    plt.xlabel('时间 (采样点)')
                    plt.ylabel('输出值')
                    plt.grid(True)
                
                plt.tight_layout()
                plt.savefig(os.path.join(output_dir, '电机输出对比图.png'), dpi=300, bbox_inches='tight')
                plt.close()
                print("✓ 生成电机输出对比图")
            
            # 示例2: 陀螺仪数据图
            gyro_fields = [f for f in field_names if 'gyro' in f.lower()]
            if len(gyro_fields) >= 3:
                plt.figure(figsize=(12, 10))
                axes = ['Roll', 'Pitch', 'Yaw']
                for i, field in enumerate(gyro_fields[:3]):
                    plt.subplot(3, 1, i+1)
                    plt.plot(data[field])
                    plt.title(f'{axes[i]}轴陀螺仪数据 ({field})')
                    plt.xlabel('时间 (采样点)')
                    plt.ylabel('角速度 (度/秒)')
                    plt.grid(True)
                
                plt.tight_layout()
                plt.savefig(os.path.join(output_dir, '陀螺仪数据图.png'), dpi=300, bbox_inches='tight')
                plt.close()
                print("✓ 生成陀螺仪数据图")
            
            # 示例3: 电池数据图
            battery_fields = [f for f in field_names if any(keyword in f.lower() for keyword in ['vbat', 'current', 'voltage'])]
            if battery_fields:
                plt.figure(figsize=(12, 6))
                for i, field in enumerate(battery_fields[:2]):
                    plt.subplot(1, 2, i+1)
                    plt.plot(data[field])
                    plt.title(f'{field}')
                    plt.xlabel('时间 (采样点)')
                    plt.ylabel('值')
                    plt.grid(True)
                
                plt.tight_layout()
                plt.savefig(os.path.join(output_dir, '电池数据图.png'), dpi=300, bbox_inches='tight')
                plt.close()
                print("✓ 生成电池数据图")
            
            print(f"\n示例图表已保存到: {output_dir}")
            
        except Exception as e:
            print(f"创建示例图表时出错: {e}")

def main():
    # 日志文件路径
    log_files = [
        "d:/Git/FlightRecord/SFPV_85/record/btfl_001.bbl",
        "d:/Git/FlightRecord/SFPV_85/record/btfl_002.bbl",
        "d:/Git/FlightRecord/SFPV_85/record/btfl_all.bbl"
    ]
    
    # 创建分析器
    analyzer = DataFieldAnalyzer(log_files)
    
    # 分析所有文件
    analyzer.analyze_all_files()
    
    # 生成报告
    report = analyzer.generate_analysis_report()
    
    # 保存报告
    output_dir = "d:/Git/FlightRecord/SFPV_85/field_analysis_results"
    os.makedirs(output_dir, exist_ok=True)
    
    with open(os.path.join(output_dir, "数据字段分析报告.md"), 'w', encoding='utf-8') as f:
        f.write('\n'.join(report))
    
    # 创建示例可视化
    analyzer.create_sample_visualizations()
    
    print(f"\n=== 分析完成 ===")
    print(f"报告已保存到: {output_dir}")
    print(f"\n发现的主要数据类别:")
    for category, fields in analyzer.field_categories.items():
        if fields:
            unique_fields = list(set(fields))
            print(f"- {category}: {len(unique_fields)}个字段")
    
    print(f"\n总计: {len(analyzer.all_fields)} 个不同的数据字段")
    print("\n详细信息请查看生成的报告文件。")

if __name__ == "__main__":
    main()